package com.zl.gmadmin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.gmadmin.entity.SysJob;
import com.zl.gmadmin.entity.SysRole;
import com.zl.gmadmin.entity.SysUser;
import com.zl.gmadmin.exception.UserException;
import com.zl.gmadmin.mapper.SysUserMapper;
import com.zl.gmadmin.payload.UserQueryCriteria;
import com.zl.gmadmin.service.SysUserService;
import com.zl.gmadmin.utils.Builder;
import com.zl.gmadmin.utils.FileUtil;
import com.zl.gmadmin.utils.LogUtil;
import com.zl.gmadmin.utils.PageUtils;
import com.zl.gmadmin.vo.user.SysUserVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangliang
 * @version 1.0
 * @date 2021/2/2 15:31
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {


    private final SysUserMapper sysUserMapper;

    public SysUserServiceImpl(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    @Override
    public Object selectPageVo(UserQueryCriteria queryCriteria, Page<SysUser> page) {
        IPage<SysUser> sysUserIPage = sysUserMapper.selectPageVo(page);
        List<SysUser> users = sysUserIPage.getRecords();
        List<SysUserVo> sysUserVos = users.stream().map(user -> {
                    SysUserVo sysUserVo = Builder.of(SysUserVo::new)
                            .with(SysUserVo::setId, user.getUserId())
                            .with(SysUserVo::setAvatarName, user.getAvatarName())
                            .with(SysUserVo::setAvatarPath, user.getAvatarPath())
                            .with(SysUserVo::setCreateBy, user.getCreateBy())
                            .with(SysUserVo::setCreateTime, user.getCreateTime())
                            .with(SysUserVo::setDept, user.getDept())
                            .with(SysUserVo::setDeptId, user.getDeptId())
                            .with(SysUserVo::setEmail, user.getEmail())
                            .with(SysUserVo::setEnabled, user.getEnabled())
                            .with(SysUserVo::setGender, user.getGender())
                            .with(SysUserVo::setIsAdmin, user.getIsAdmin())
                            .with(SysUserVo::setNickName, user.getNickName())
                            .with(SysUserVo::setPhone, user.getPhone())
                            .with(SysUserVo::setPwdResetTime, user.getPwdResetTime())
                            .with(SysUserVo::setRoles, user.getRoles())
                            .with(SysUserVo::setUpdateBy, user.getUpdateBy())
                            .with(SysUserVo::setUpdateTime, user.getUpdateTime())
                            .with(SysUserVo::setUsername, user.getUsername())
                            .with(SysUserVo::setJob, user.getJobs())
                            .build();
                    return sysUserVo;
                }
        ).collect(Collectors.toList());

        return PageUtils.toPage(sysUserVos.stream().collect(Collectors.toList()), sysUserIPage.getTotal());
    }

    @Override
    public Optional<SysUser> findByUsernameOrEmailOrPhone(String usernameOrEmailOrPhone) {
        return sysUserMapper.findByUsernameOrEmailOrPhone(usernameOrEmailOrPhone);
    }

    @Transactional(rollbackFor = UserException.class)
    @Override
    public Object insert(SysUser user, List<SysRole> roles, List<SysJob> sysJobs) {
        Object O = sysUserMapper.insertUserWithoutRole(user);
        roles.forEach(role -> sysUserMapper.insertUser_Role(user, role));
        sysJobs.forEach(sysJob -> sysUserMapper.insertUser_job(user, sysJob));
        return O;
    }

    @Transactional(rollbackFor = UserException.class)
    @Override
    public void delUsers(List<Long> ids) {
//        删除角色用户中间表信息
        sysUserMapper.deleteUser_role(ids);
//        删除用户与job中间表
        sysUserMapper.deleteUser_job(ids);
        sysUserMapper.deleteBatchIds(ids);
    }

    @Transactional(rollbackFor = UserException.class)
    @Override
    public boolean updateUserById(SysUser sysUser, List<SysRole> sysRoles, List<SysJob> sysJobs) {
//        sysUser.setDeptId(sysUser.getDept().getId());
        if (ObjectUtil.isNotEmpty(sysUserMapper.updateById(sysUser))) {
            // 更新角色
            Long id = sysUser.getUserId();
            if (ObjectUtil.isNotEmpty(sysRoles)) {

                LogUtil.debug("更新角色");
                LogUtil.debug(JSONUtil.toJsonStr(id));
                sysUserMapper.deleteUser_role(Collections.singletonList(id));
                for (SysRole role : sysRoles
                ) {
                    sysUserMapper.insertUser_Role(sysUser, role);
                }
            }
//           更新职位
            if (ObjectUtil.isNotEmpty(sysJobs)) {

                sysUserMapper.deleteUser_job(Collections.singletonList(id));
                for (SysJob job : sysJobs
                ) {
                    sysUserMapper.insertUser_job(sysUser, job);
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public void download(HttpServletResponse response, List<Long> ids) throws IOException {

        List<SysUser> sysUsers = sysUserMapper.findAll(ids);

        LogUtil.debug("导出:" + JSONUtil.toJsonStr(sysUsers));
        List<Map<String, Object>> mapList = new ArrayList<>();

        for (SysUser sysUser : sysUsers) {
            Map<String, Object> map = new LinkedHashMap<>();
            List<String> jobs = sysUser.getJobs().stream().map(SysJob::getName).collect(Collectors.toList());
            List<String> roles = sysUser.getRoles().stream().map(SysRole::getName).collect(Collectors.toList());

            map.put("用户名", sysUser.getUsername());
            map.put("昵称", sysUser.getNickName());
            map.put("性别", sysUser.getGender());
            map.put("电话", sysUser.getPhone());
            map.put("邮箱", sysUser.getEmail());
            map.put("部门", sysUser.getDept().getName());
            map.put("职位", jobs);

            map.put("状态", sysUser.getEnabled());

            map.put("角色", roles);
            map.put("创建人", sysUser.getCreateBy());
            map.put("更新人", sysUser.getUpdateBy());
            map.put("创建日期", sysUser.getCreateTime());
            map.put("更新日期", sysUser.getUpdateTime());
            mapList.add(map);
        }


        FileUtil.downloadExcel(mapList, response);
    }


}
